/**
 * @(#)AdministradorConfiguracionBaseDatos.java 18/11/2010
 *
 * Copyright (c) 2007-2012 PsiqueWare S.A. de C.V. All Rights Reserved.
 * This software is the proprietary information of PsiqueWare S.A. de C.V.
 * Use is subject to license terms.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * <br/>Usuario : AngelElectrico
 * <br/>Creaci&oacute;n: 18/11/2010 - 06:53:30 PM
 * <br/>
 * <br/>
 * <br/><t5>Cambios :</t5>
 * <br/><b>Fecha | Autor  |  Cambios</b>
 * <ul>
 * <li>18/11/2010 | <a href = "mailto:AngelElectrico@PsiqueWare.com">&Aacute;ngel El&eacute;ctrico</a> | Creaci&oacute;n del Objeto.</li>
 *
 * </ul>
 */

package com.psiqueware.alheli.configuracion.basedatos;

import com.psiqueware.alheli.configuracion.AbstractAdministradorConfiguracion;
import com.psiqueware.alheli.configuracion.basedatos.dao.ConfiguracionDAOFactory;
import com.psiqueware.alheli.configuracion.basedatos.dao.ValorConfiguradoDAO;
import com.psiqueware.alheli.configuracion.basedatos.modelo.ValorConfiguradoK;
import com.psiqueware.alheli.dao.EnlaceTransaccional;
import com.psiqueware.alheli.dao.TipoDAO;
import com.psiqueware.alheli.exception.NullArgumentException;
import com.psiqueware.alheli.logging.Logger;
import com.psiqueware.alheli.logging.LoggerFactory;

/**
 * {@link AdministradorConfiguracion} que almacena la informaci&oacute;n en una base de datos.
 * <br/>Paquete Original: com.psiqueware.alheli.configuracion.basedatos
 * <br/>Nombre  Original: AdministradorConfiguracionBaseDatos
 * <br/>Oprima para ver : <a href="AdministradorConfiguracionBaseDatos.java.html"><i>C&oacute;digo Fuente</i> </a>
 *
 * @author <a href="mailto:AngelElectrico@PsiqueWare.com">AngelElectrico</a>
 * @version Revision: 1.1 18/11/2010 06:53:30 PM
 */
public final class AdministradorConfiguracionBaseDatos extends AbstractAdministradorConfiguracion
{

    /**
     * Logger de clase para AdministradorConfiguracionBaseDatos
     */
    private static final Logger s_log = LoggerFactory.getLogger(AdministradorConfiguracionBaseDatos.class);


    private final TipoDAO m_tipo;


    /**
     * Constructor de AdministradorConfiguracionBaseDatos.
     */
    public AdministradorConfiguracionBaseDatos(final TipoDAO tipo)
    {
        m_tipo = tipo;
    }


    /**
     * Agrega un atributo de configuraci&oaucte;n.
     *
     * @param idDominio identificador &uacute;nico del dominio al que pertence el contexto.Puede ser <code>null</code>, siendo <code>null</code> un dominio distinto de otros.
     * @param contexto  del atributo. No puede ser <code>null</code> ni vacio.
     * @param nombre    del atributo. No puede ser <code>null</code> ni vacio.
     * @param valor     a almacenar.
     */
    public void configura(final Long idDominio, final String contexto, final String nombre, final String valor)
    {
        if (null == contexto)
            throw new NullArgumentException("<error>El argumento 'contexto' no puede ser NULL.</error>");
        if (null == nombre) throw new NullArgumentException("<error>El argumento 'nombre' no puede ser NULL.</error>");
        configuraGeneral(idDominio, contexto, nombre, valor);
    }

    private void configuraGeneral(final Long idDominio, final String contexto, final String nombre, final String valor)
    {
        ValorConfigurado valorConfigurado = buscaValorConfigurado(idDominio, contexto, nombre);
        if (null == valorConfigurado)
        {
            valorConfigurado = new ValorConfiguradoK(idDominio, contexto, nombre, valor);
            final EnlaceTransaccional enlaceTransaccional = ConfiguracionDAOFactory.nuevoEnlace(m_tipo);

            try
            {
                enlaceTransaccional.iniciaTransaccion();
                final ValorConfiguradoDAO daoValorConfigurado = ConfiguracionDAOFactory.findDAOValorConfigurado(enlaceTransaccional);

                valorConfigurado = daoValorConfigurado.saveValorConfigurado(valorConfigurado, enlaceTransaccional);
            }
            catch (Exception e)
            {
                final String error = "<error><msg>No se pudo localizar el ValorConfigurado.</msg><parametros><idDominio>" + idDominio + "</idDominio><contexto>" + contexto + "</contexto><nombre>" + nombre + "</nombre></parametros></error>";
                s_log.error(error);
                s_log.error(e);
                enlaceTransaccional.rollBack();
            }
            finally
            {
                enlaceTransaccional.finalizaTransaccion();
            }

        }
        else
        {
            final ValorConfiguradoK oK = (ValorConfiguradoK) valorConfigurado;
            oK.setValor(valor);

            final EnlaceTransaccional enlaceTransaccional = ConfiguracionDAOFactory.nuevoEnlace(m_tipo);

            try
            {
                enlaceTransaccional.iniciaTransaccion();
                final ValorConfiguradoDAO daoValorConfigurado = ConfiguracionDAOFactory.findDAOValorConfigurado(enlaceTransaccional);

                valorConfigurado = daoValorConfigurado.updateValorConfigurado(valorConfigurado, enlaceTransaccional);
            }
            catch (Exception e)
            {
                final String error = "<error><msg>No se pudo localizar el VarlosConfigurado.</msg><parametros><idDominio>" + idDominio + "</idDominio><contexto>" + contexto + "</contexto><nombre>" + nombre + "</nombre></parametros></error>";
                s_log.error(error);
                s_log.error(e);
                enlaceTransaccional.rollBack();
            }
            finally
            {
                enlaceTransaccional.finalizaTransaccion();
            }
        }
    }

    /**
     * Agrega un atributo de configuraci&oaucte;n.
     *
     * @param contexto del atributo. No puede ser <code>null</code> ni vacio.
     * @param nombre   del atributo. No puede ser <code>null</code> ni vacio.
     * @param valor    a almacenar.
     */
    public void configura(final String contexto, final String nombre, final String valor)
    {
        if (null == contexto)
            throw new NullArgumentException("<error>El argumento 'contexto' no puede ser NULL.</error>");
        if (null == nombre) throw new NullArgumentException("<error>El argumento 'nombre' no puede ser NULL.</error>");
        configuraGeneral(null, contexto, nombre, valor);
    }

    /**
     * Agrega un atributo de configuraci&oaucte;n.
     *
     * @param nombre del atributo. No puede ser <code>null</code> ni vacio.
     * @param valor  a almacenar.
     */
    public void configura(final String nombre, final String valor)
    {
        if (null == nombre) throw new NullArgumentException("<error>El argumento 'nombre' no puede ser NULL.</error>");
        configuraGeneral(null, null, nombre, valor);
    }

    /**
     * Busca un atributo de  configuraci&oaucte;n.
     *
     * @param idDominio       identificador &uacute;nico del dominio al que pertence el contexto. Puede ser <code>null</code>, siendo <code>null</code> un dominio distinto de otros.
     * @param contexto        del atributo buscado. No puede ser <code>null</code> ni vacio.
     * @param nombre          del atributo buscado. No puede ser <code>null</code> ni vacio.
     * @param valorPorDefecto en caso de que el atributo no se haya dado de alta.
     *
     * @return cadena con el valor guardado del atributo; el valorPorDefecto en caso de no tener almacenado ning&uacute;n valor.
     */
    public String busca(final Long idDominio, final String contexto, final String nombre, final String valorPorDefecto)
    {
        if (null == contexto)
            throw new NullArgumentException("<error>El argumento 'contexto' no puede ser NULL.</error>");
        if (null == nombre) throw new NullArgumentException("<error>El argumento 'nombre' no puede ser NULL.</error>");
        ValorConfigurado valorConfigurado = buscaValorConfigurado(idDominio, contexto, nombre);

        return null == valorConfigurado ? valorPorDefecto : valorConfigurado.getValor();
    }

    /**
     * Busca un atributo de  configuraci&oaucte;n.
     *
     * @param contexto        del atributo buscado. No puede ser <code>null</code> ni vacio.
     * @param nombre          del atributo buscado. No puede ser <code>null</code> ni vacio.
     * @param valorPorDefecto en caso de que el atributo no se haya dado de alta.
     *
     * @return cadena con el valor guardado del atributo; el valorPorDefecto en caso de no tener almacenado ning&uacute;n valor.
     */
    public String busca(final String contexto, final String nombre, final String valorPorDefecto)
    {
        if (null == contexto)
            throw new NullArgumentException("<error>El argumento 'contexto' no puede ser NULL.</error>");
        if (null == nombre) throw new NullArgumentException("<error>El argumento 'nombre' no puede ser NULL.</error>");
        ValorConfigurado valorConfigurado = buscaValorConfigurado(null, contexto, nombre);

        return null == valorConfigurado ? valorPorDefecto : valorConfigurado.getValor();
    }

    /**
     * Busca un atributo de  configuraci&oaucte;n.
     *
     * @param nombre          del atributo buscado. No puede ser <code>null</code> ni vacio.
     * @param valorPorDefecto en caso de que el atributo no se haya dado de alta.
     *
     * @return cadena con el valor guardado del atributo; el valorPorDefecto en caso de no tener almacenado ning&uacute;n valor.
     */
    public String busca(final String nombre, final String valorPorDefecto)
    {
        if (null == nombre) throw new NullArgumentException("<error>El argumento 'nombre' no puede ser NULL.</error>");
        ValorConfigurado valorConfigurado = buscaValorConfigurado(null, null, nombre);

        return null == valorConfigurado ? valorPorDefecto : valorConfigurado.getValor();
    }

    private ValorConfigurado buscaValorConfigurado(final Long idDominio, final String contexto, final String nombre)
    {
        final EnlaceTransaccional enlaceTransaccional = ConfiguracionDAOFactory.nuevoEnlace(m_tipo);

        ValorConfigurado valorConfigurado = null;
        try
        {
            enlaceTransaccional.iniciaTransaccion();
            final ValorConfiguradoDAO daoValorConfigurado = ConfiguracionDAOFactory.findDAOValorConfigurado(enlaceTransaccional);

            valorConfigurado = daoValorConfigurado.findValorConfiguradoPorIdDominioContextoNombre(idDominio, contexto, nombre, enlaceTransaccional);
        }
        catch (Exception e)
        {
            final String error = "<error><msg>No se pudo localizar el ValorConfigurado.</msg><parametros><idDominio>" + idDominio + "</idDominio><contexto>" + contexto + "</contexto><nombre>" + nombre + "</nombre></parametros></error>";
            s_log.error(error);
            s_log.error(e);
            enlaceTransaccional.rollBack();
        }
        finally
        {
            enlaceTransaccional.finalizaTransaccion();
        }
        return valorConfigurado;
    }
}

